<?php
/**
 * Loader.php
 *
 * LICENSE
 *
 * This source file is intellectual property of Angry Bytes BV
 *
 * Angry Bytes BV
 * PC Hooftweg 5
 * 1217 RJ Hilversum
 * The Netherlands
 * Tel: +31 (0) 35 629 5470
 * Fax: +31 (0) 35 629 4820
 * Email: info@angrybytes.com
 *
 * @category    Abc
 * @package     Abc_Loader
 */

/**
 * @see Zend_Controller_Action_HelperBroker
 */
require_once 'Zend/Controller/Action/HelperBroker.php';

/**
 * Abc_Loader
 *
 * a loader for forms and models from module directories (which aren't in the include path)
 *
 * @category    Abc
 * @package     Abc_Loader
 */
class Naneau_Loader
{
    /**
     * form path spec
     *
     * @var string
     */
    protected static $_formPathSpec = ':moduleDir/forms';
    
    /**
     * Get the modelLoader
     *
     * @return Zend_Controller_Action_Helper_ModelLoader
     */
    public static function getLoader()
    {
        return Zend_Controller_Action_HelperBroker::getStaticHelper('modelLoader');
    }

    /**
     * Load a model using the modelLoader action helper
     *
     * @param string $model
     * @return mixed|string|false
     */
    public static function loadModel($model)
    {
        return self::getLoader()->load($model);
    }

    /**
     * loadForms()
     *
     * @param string|array $forms
     * @return void
     */
    public static function loadForms($forms)
    {
        $forms = (array) $forms;
        //in array form

        $frontController = Zend_Controller_Front::getInstance();
        //the front controller

        $modules = array_keys($frontController->getControllerDirectory());
        //all modules currently in the application

        $moduleDirs = array();
        foreach($frontController->getControllerDirectory() as $name => $dir) {
            $moduleDirs[$name] = realpath($dir . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
            //translate into the real path (which is one dir above the controller dir)
        }
        //an array of module name => module directory

        foreach ($forms as $form) {
            $split = split('_', $form);
            //form split
            foreach($split as $key => $item) {
                $split[$key] = ucfirst($item);
            }
            //normalize split array to upper case

            $form = implode('_', $split);
            //normalized form name

            if (class_exists($form)) {
                continue;
            }
            //if the class exists, do nothing (go to next)

            $requestModule = array_shift($split);
            $requestModule[0] = strtolower($requestModule[0]);
            //requested module (normalized)

            if (!in_array($requestModule, $modules)) {
                //the request module doesn't exist
                throw new Exception('Module ' . $requestModule . ' does not exist, can\'t load form ' . $form);
            }

            $path = str_replace(':moduleDir', $moduleDirs[$requestModule] , self::$_formPathSpec) . DIRECTORY_SEPARATOR;
            //the path inside the module dir we'll be looking for the form


            $file = array_pop($split) . '.php';
            //the file we're going to load

            $subdir = implode(DIRECTORY_SEPARATOR, $split);
            //the sub dir is what's left of $split

            $path = $path . $subdir . DIRECTORY_SEPARATOR;

            Zend_Loader::loadFile($file, $path);

            if (!class_exists($form)) {
                throw new Zend_Controller_Action_Exception($form . ' not found, file: ' . $path . $file);
            }
            //check if we loaded the form right
        }
    }
    
    /**
     * get a form instance
     *
     * @param string $form
     * @return Zend_Form
     */
    public static function getForm($form) {
        self::loadForms($form);
        
        return new $form;
    }
    
    /**
     * get a model if there's a request param for one
     *
     * @param string $table
     * @param string|int $siteId
     * @return Base_Base
     * @todo move to static method in model class
     */
    public static function getBase($table = null, $siteId = null)
    {
        self::loadModel('Base_Factory');
        //base model

        if ($siteId == null) {
            $siteId = Abc_Application::getSiteId();
        }
         
        if ($table == null) {
            $table = Zend_Controller_Front::getInstance()->getRequest()->getParam('table');
        }
        if ($table == null) {
            throw new Exception('Can\'t find table');
        }

        return Base_Factory::factory($table, $siteId);
    }
}